package com.solution.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import com.solution.constant.LoginConstants;
import com.solution.delegate.ExaminationServiceDelegate;
import com.solution.delegate.UserInfoServiceDelegate;
import com.solution.exception.DelegateException;
import com.solution.exception.ServiceBeanException;
import com.solution.form.ExamineeForm;
import com.solution.model.AnswerType;
import com.solution.model.ExamCategoryLevelMapping;
import com.solution.model.QuestionType;
import com.solution.model.UserInfo;
import com.solution.model.UserQuestionMapping;
import com.solution.model.UserQuestionMappingId;
import com.solution.util.SearchVO;

public class ExamineeAction extends Action {
	/**
	 * logging instance.
	 */
	private Logger logger = Logger.getLogger(ExamineeAction.class.getName());

	/**
	 * Default method.
	 */
	public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		logger.debug("Entering :: ExamineeAction:execute()");
		ExamineeForm examineeForm =(ExamineeForm)form;
		/**
		 * Show Question Case.
		 */
		if("/examineeDashboard".equals(mapping.getPath())){
			return examineeDashboard(mapping, examineeForm, request, response);
		}
		/**
		 * Show Question Case.
		 */
		if("/showQuestion".equals(mapping.getPath())){
			return showQuestion(mapping, examineeForm, request, response);
		}
		if("/showAjaxQuestion".equals(mapping.getPath())){
			return showAjaxQuestion(mapping, examineeForm, request, response);
		}
		if("/finishExam".equals(mapping.getPath())){
			return finishExam(mapping, examineeForm, request, response);
		}
		if("/examineeLogout".equals(mapping.getPath()))
		{
			return examineeLogout(mapping, examineeForm,request);
		}
		return null;
	}
	
	public ActionForward examineeLogout(ActionMapping mapping,ExamineeForm examForm, HttpServletRequest request ) throws IOException, ServletException
    {
		return mapping.findForward("success");
    }
	
	public ActionForward examineeDashboard(ActionMapping mapping,ExamineeForm examForm,HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		logger.debug("Entering :: ExamAction:examineeDashboard()");
		ActionMessages errors  = new ActionErrors() ;
		try{
			HttpSession session = request.getSession();
			UserInfo userInfo = null;
			if(session != null){
				userInfo = (UserInfo)session.getAttribute(LoginConstants.SESSION_USER_INFO);
			}
			
			ExaminationServiceDelegate examinationServiceDelegate = new ExaminationServiceDelegate();
			SearchVO searchVO =  new SearchVO();
			searchVO.addEqualsCondition("id.examTypeId", userInfo.getExamTypeId(),true);
			List<ExamCategoryLevelMapping> examLevelCategoryMappingList = examinationServiceDelegate.fetchExamCategoryLevelMapping(searchVO);
			searchVO.clear();
			List<QuestionType> finalQuestionTypeList = new ArrayList<QuestionType>();
			for(ExamCategoryLevelMapping examCategoryLevelMappingTemp:examLevelCategoryMappingList){
				Set<QuestionType> questionTypeList = examinationServiceDelegate.fetchActiveQuestions(examCategoryLevelMappingTemp.getCategoryType().getId(), examCategoryLevelMappingTemp.getLevelType().getId(), examCategoryLevelMappingTemp.getNumberQuestions());
				finalQuestionTypeList.addAll(questionTypeList);
			}
			session.setAttribute(LoginConstants.EXAMINEE_QUESTIONS, finalQuestionTypeList);
			/*Used to save Question Id and Anwer ID for User*/
			HashMap<Long, Long> questionAnswerMapping = new HashMap<Long, Long>();
//			for(QuestionType questionType:finalQuestionTypeList){
//				questionAnswerMapping.put(questionType.getId(), null);
//			}
			examForm.setExamType(examinationServiceDelegate.getExam(userInfo.getExamTypeId()));
			session.setAttribute(LoginConstants.EXAMINEE_QUESTION_ANSWER, questionAnswerMapping);	
			session.setAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX, new Integer(0));
		}
		catch(ServiceBeanException sbe){
			logger.error(sbe);
			errors.add("error", new ActionMessage("Examinee.fail.exception", sbe.getMessage()));
			examForm.setExamCreated("NO");
		}
		catch(DelegateException de){
			logger.error(de);
			errors.add("error", new ActionMessage("Examinee.dashboard.fail"));
		}
		saveErrors(request, errors);
		logger.debug("Exiting :: ExamAction:examineeDashboard()");
		return mapping.findForward("examineeDashboard");
	}
	
	public ActionForward showQuestion(ActionMapping mapping,ExamineeForm examForm,HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		logger.debug("Entering :: ExamAction:showQuestion()");
		ActionMessages errors  = new ActionErrors() ;
		try{
			HttpSession session = request.getSession();
			UserInfo userInfo = null;
			if(session != null){
				userInfo = (UserInfo)session.getAttribute(LoginConstants.SESSION_USER_INFO);
			} 

			List<QuestionType> questionTypeList =(List<QuestionType>)session.getAttribute(LoginConstants.EXAMINEE_QUESTIONS);
			Integer index = (Integer)session.getAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX);
			/*Increase or decrease index*/
			//session.setAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX,index+1);
			
			ExaminationServiceDelegate examinationServiceDelegate = new ExaminationServiceDelegate();
			examForm.setAnswerTypeList(examinationServiceDelegate.fetchActiveAnswers(questionTypeList.get(index).getId()));
			examForm.setExamType(examinationServiceDelegate.getExam(userInfo.getExamTypeId()));
			
			// update the user status so that he cannot login again.
//			userInfo.setStatus(LoginConstants.USER_BLOCKED);
//			UserInfoServiceDelegate userInfoService= new UserInfoServiceDelegate();
//			userInfoService.update(userInfo);
		}
		catch(ServiceBeanException sbe){
			logger.error(sbe);
			errors.add("error", new ActionMessage("Exam.fail.exception", sbe.getMessage()));
		}
		catch(DelegateException de){
			logger.error(de);
			errors.add("error", new ActionMessage("Exam.details.fail"));
		}
		saveErrors(request, errors);
		logger.debug("Exiting :: ExamAction:showQuestion()");
		return mapping.findForward("examineeQuestion");
	}
	public ActionForward showAjaxQuestion(ActionMapping mapping,ExamineeForm examineeForm,HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		logger.debug("Entering :: ExamAction:showAjaxQuestion()");
			ActionMessages errors  = new ActionErrors() ;
		try{
			HttpSession session = request.getSession();
			List<QuestionType> questionTypeList =(List<QuestionType>)session.getAttribute(LoginConstants.EXAMINEE_QUESTIONS);
			Integer index = (Integer)session.getAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX);
			HashMap<Long, Long> qesAnswer = (HashMap<Long, Long>)session.getAttribute(LoginConstants.EXAMINEE_QUESTION_ANSWER);
			if(examineeForm.getAnswerId()!=-1){				
				qesAnswer.put(questionTypeList.get(index).getId(), examineeForm.getAnswerId());
			}else{
				qesAnswer.remove(questionTypeList.get(index).getId());
			}
			ExaminationServiceDelegate examinationServiceDelegate = new ExaminationServiceDelegate();
			
			/*Increase or decrease index*/
			if("next".equalsIgnoreCase(examineeForm.getNextOrPrevious())){
				if(index<questionTypeList.size()-1){
					session.setAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX,index+1);
					examineeForm.setAnswerTypeList(examinationServiceDelegate.fetchActiveAnswers(questionTypeList.get(index+1).getId()));					
				}else{
					examineeForm.setAnswerTypeList(examinationServiceDelegate.fetchActiveAnswers(questionTypeList.get(index).getId()));					
				}
			}else{
				if(index>0){
					session.setAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX,index-1);
					examineeForm.setAnswerTypeList(examinationServiceDelegate.fetchActiveAnswers(questionTypeList.get(index-1).getId()));					
				}else{
					examineeForm.setAnswerTypeList(examinationServiceDelegate.fetchActiveAnswers(questionTypeList.get(index).getId()));					
				}
			}
			
			
			
		}
		catch(ServiceBeanException sbe){
			logger.error(sbe);
			errors.add("error", new ActionMessage("Exam.fail.exception", sbe.getMessage()));
		}
		catch(DelegateException de){
			logger.error(de);
			errors.add("error", new ActionMessage("Exam.details.fail"));
		}
		saveErrors(request, errors);
		logger.debug("Exiting :: ExamAction:showAjaxQuestion()");
		return mapping.findForward("examineeAjaxQuestion");
	}
	public ActionForward finishExam(ActionMapping mapping,ExamineeForm examineeForm,HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		logger.debug("Entering :: ExamAction:finishExam()");
			ActionMessages errors  = new ActionErrors() ;
		try{
			ExaminationServiceDelegate examinationServiceDelegate = new ExaminationServiceDelegate();
			UserInfoServiceDelegate userService = new UserInfoServiceDelegate();
			HttpSession session = request.getSession();
			UserInfo userInfo = null;
			if(session != null){
				userInfo = (UserInfo)session.getAttribute(LoginConstants.SESSION_USER_INFO);
			} 			
			Integer index = (Integer)session.getAttribute(LoginConstants.EXAMINEE_QUESTION_INDEX);
			HashMap<Long, Long> quesAnswer = (HashMap<Long, Long>)session.getAttribute(LoginConstants.EXAMINEE_QUESTION_ANSWER);
			List<UserQuestionMapping> userQuestionMappingList = new ArrayList<UserQuestionMapping>();
			List<QuestionType> questionTypeList =(List<QuestionType>)session.getAttribute(LoginConstants.EXAMINEE_QUESTIONS);
			Iterator<QuestionType> questionItr = questionTypeList.iterator();
			QuestionType questionType = null;
			AnswerType answerType = null;
			UserQuestionMapping userQuestionMapping = null;
			UserQuestionMappingId userQuestionMappingId = null;
			int correctAnswerCount = 0;
			Date createdOn = new Date();
			while(questionItr.hasNext())
			{
				questionType = questionItr.next();
				userQuestionMapping = new UserQuestionMapping();
				userQuestionMappingId = new UserQuestionMappingId();
				userQuestionMappingId.setUserInfoId(userInfo.getId());
				userQuestionMappingId.setQuestionTypeId(questionType.getId());
				userQuestionMapping.setId(userQuestionMappingId);
				userQuestionMapping.setCreatedBy(userInfo.getUsername());
				userQuestionMapping.setCreatedOn(createdOn);
				answerType = new AnswerType();
				userQuestionMapping.setQuestionType(questionType);
				userQuestionMapping.setUserInfo(userInfo);
				if(quesAnswer.get(questionType.getId())!=null){
					answerType.setId(quesAnswer.get(questionType.getId()));
					userQuestionMapping.setAnswerType(answerType);
					AnswerType correctAnswer = examinationServiceDelegate.fetchCorrectAnswer(questionType.getId());
					if(correctAnswer.getId().equals(quesAnswer.get(questionType.getId()))){
						correctAnswerCount++;
					}
				}
				userQuestionMappingList.add(userQuestionMapping);
				
			}
			userService.createUserQuestionMappings(userQuestionMappingList);
			userInfo.setExamScore(new Long(correctAnswerCount));
			userInfo.setStatus(LoginConstants.USER_BLOCKED);
			userService.update(userInfo);
		}
		catch(ServiceBeanException sbe){
			logger.error(sbe);
			errors.add("error", new ActionMessage("Exam.fail.exception", sbe.getMessage()));
		}
		catch(DelegateException de){
			logger.error(de);
			errors.add("error", new ActionMessage("Exam.details.fail"));
		}
		saveErrors(request, errors);
		logger.debug("Exiting :: ExamAction:finishExam()");
		return mapping.findForward("finishExam");
	}


}
